package com.processmining.service.impl;

import java.io.File;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.deckfour.xes.model.XLog;
import org.springframework.stereotype.Service;

import com.processmining.controller.MiningController;
import com.processmining.entity.Algo;
import com.processmining.service.IMiningService;
import com.processmining.util.MiningResult;
import com.processmining.util.request.MiningData;

import net.ProcessMining.models.heuristics.HeuristicsNet;

@Service
public class MiningServiceImpl implements IMiningService{

	
	
	private static Logger logger = LogManager.getLogger(MiningServiceImpl.class.getName());
	
	
	@Override
	public MiningResult logMine(MiningData miningData, XLog eventLog, Algo algo, Map<String, Object> map) throws MalformedURLException, NoSuchMethodException, SecurityException, ClassNotFoundException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
		String path = algo.getPath();
		//System.out.println(path);
		File file=new File(path); // jar包的路径
		URL url=file.toURI().toURL();
		
		URLClassLoader loader = new URLClassLoader(new URL[]{url},MiningController.class.getClassLoader());
		// 反射调用jar包里的方法
		Constructor c2 = loader.loadClass(algo.getPackagename()+"."+algo.getClassname()).getConstructor();
		Object minerObj =  c2.newInstance();
		Method method2 = minerObj.getClass().getMethod(algo.getMethod(), XLog.class,HashMap.class);// util.getMethod(hmObj.getClass(), methodName,XLog.class,HashMap.class);	
		HeuristicsNet net = (HeuristicsNet) method2.invoke(minerObj,eventLog,map);		// 调用mine()挖掘
		
		
		// 获取其他结果
		Method m = minerObj.getClass().getMethod("getUsedTime");
		String time = (String) m.invoke(minerObj);
		
		Method tracesM = minerObj.getClass().getMethod("getTraces");
		List<String> traces = (List<String>) tracesM.invoke(minerObj);
		
		Method allTracesM = minerObj.getClass().getMethod("getAllTraces");
		List<String> allTraces = (List<String>) allTracesM.invoke(minerObj);
		
		System.out.println(net.getClass().toString());
		MiningResult result = new MiningResult();
		result.setAllTraces(allTraces);
		result.setTraces(traces);
		result.setUsedTime(time);
		result.setMiningData(miningData);
		result.setNet(net);
		        		
      
		return result;
	}

}
